home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Mac / Modules / qd / qdsupport.py < prev   
Text File  |  1996-05-08  |  13KB  |  375 lines

  1. # This script generates a Python interface for an Apple Macintosh Manager.
  2. # It uses the "bgen" package to generate C code.
  3. # The function specifications are generated by scanning the mamager's header file,
  4. # using the "scantools" package (customized for this particular manager).
  5.  
  6. import string
  7.  
  8. import addpack
  9. addpack.addpack(':Tools:bgen:bgen')
  10.  
  11. # Declarations that change for each manager
  12. MACHEADERFILE = 'QuickDraw.h'        # The Apple header file
  13. MODNAME = 'Qd'                # The name of the module
  14. OBJECTNAME = 'Graf'            # The basic name of the objects used here
  15.  
  16. # The following is *usually* unchanged but may still require tuning
  17. MODPREFIX = MODNAME            # The prefix for module-wide routines
  18. OBJECTTYPE = OBJECTNAME + 'Ptr'        # The C type used to represent them
  19. OBJECTPREFIX = MODPREFIX + 'Obj'    # The prefix for object methods
  20. INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
  21. EXTRAFILE = string.lower(MODPREFIX) + 'edit.py' # A similar file but hand-made
  22. OUTPUTFILE = MODNAME + "module.c"    # The file generated by this program
  23.  
  24. from macsupport import *
  25.  
  26. # Create the type objects
  27.  
  28. class TextThingieClass(FixedInputBufferType):
  29.     def getargsCheck(self, name):
  30.         pass
  31.  
  32. TextThingie = TextThingieClass(None)
  33.  
  34. # These are temporary!
  35. RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
  36. OptRgnHandle = OpaqueByValueType("RgnHandle", "OptResObj")
  37. PicHandle = OpaqueByValueType("PicHandle", "ResObj")
  38. PolyHandle = OpaqueByValueType("PolyHandle", "ResObj")
  39. PixMapHandle = OpaqueByValueType("PixMapHandle", "ResObj")
  40. PixPatHandle = OpaqueByValueType("PixPatHandle", "ResObj")
  41. PatHandle = OpaqueByValueType("PatHandle", "ResObj")
  42. CursHandle = OpaqueByValueType("CursHandle", "ResObj")
  43. CGrafPtr = OpaqueByValueType("CGrafPtr", "GrafObj")
  44. GrafPtr = OpaqueByValueType("GrafPtr", "GrafObj")
  45. BitMap_ptr = OpaqueByValueType("BitMapPtr", "BMObj")
  46. RGBColor = OpaqueType('RGBColor', 'QdRGB')
  47. RGBColor_ptr = RGBColor
  48. FontInfo = OpaqueType('FontInfo', 'QdFI')
  49.  
  50. Cursor_ptr = StructInputBufferType('Cursor')
  51. Pattern = StructOutputBufferType('Pattern')
  52. Pattern_ptr = StructInputBufferType('Pattern')
  53. PenState = StructOutputBufferType('PenState')
  54. PenState_ptr = StructInputBufferType('PenState')
  55.  
  56. includestuff = includestuff + """
  57. #include <%s>""" % MACHEADERFILE + """
  58. #include <Desk.h>
  59.  
  60. #define resNotFound -192 /* Can't include <Errors.h> because of Python's "errors.h" */
  61.  
  62. /*
  63. ** Parse/generate RGB records
  64. */
  65. PyObject *QdRGB_New(itself)
  66.     RGBColorPtr itself;
  67. {
  68.  
  69.     return Py_BuildValue("lll", (long)itself->red, (long)itself->green, (long)itself->blue);
  70. }
  71.  
  72. QdRGB_Convert(v, p_itself)
  73.     PyObject *v;
  74.     RGBColorPtr p_itself;
  75. {
  76.     long red, green, blue;
  77.     
  78.     if( !PyArg_ParseTuple(v, "lll", &red, &green, &blue) )
  79.         return 0;
  80.     p_itself->red = (unsigned short)red;
  81.     p_itself->green = (unsigned short)green;
  82.     p_itself->blue = (unsigned short)blue;
  83.     return 1;
  84. }
  85.  
  86. /*
  87. ** Generate FontInfo records
  88. */
  89. static
  90. PyObject *QdFI_New(itself)
  91.     FontInfo *itself;
  92. {
  93.  
  94.     return Py_BuildValue("hhhh", itself->ascent, itself->descent,
  95.             itself->widMax, itself->leading);
  96. }
  97.  
  98.  
  99. """
  100.  
  101. variablestuff = """
  102. {
  103.     PyObject *o;
  104.      
  105.     o = QDGA_New();
  106.     if (o == NULL || PyDict_SetItemString(d, "qd", o) != 0)
  107.         Py_FatalError("can't initialize Qd.qd");
  108. }
  109. """
  110.  
  111. ## not yet...
  112. ##
  113. ##class Region_ObjectDefinition(GlobalObjectDefinition):
  114. ##    def outputCheckNewArg(self):
  115. ##        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
  116. ##    def outputFreeIt(self, itselfname):
  117. ##        Output("DisposeRegion(%s);", itselfname)
  118. ##
  119. ##class Polygon_ObjectDefinition(GlobalObjectDefinition):
  120. ##    def outputCheckNewArg(self):
  121. ##        Output("if (itself == NULL) return PyMac_Error(resNotFound);")
  122. ##    def outputFreeIt(self, itselfname):
  123. ##        Output("KillPoly(%s);", itselfname)
  124.  
  125. class MyGRObjectDefinition(GlobalObjectDefinition):
  126.     def outputCheckNewArg(self):
  127.         Output("if (itself == NULL) return PyMac_Error(resNotFound);")
  128.     def outputCheckConvertArg(self):
  129.         OutLbrace("if (DlgObj_Check(v) || WinObj_Check(v))")
  130.         Output("*p_itself = ((GrafPortObject *)v)->ob_itself;")
  131.         Output("return 1;")
  132.         OutRbrace()
  133.     def outputGetattrHook(self):
  134.         Output("""
  135.         {    CGrafPtr itself_color = (CGrafPtr)self->ob_itself;
  136.         
  137.             if ( strcmp(name, "data") == 0 )
  138.                 return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(GrafPort));
  139.                 
  140.             if ( (itself_color->portVersion&0xc000) == 0xc000 ) {
  141.                 /* Color-only attributes */
  142.             
  143.                 if ( strcmp(name, "portBits") == 0 )
  144.                     /* XXXX Do we need HLock() stuff here?? */
  145.                     return BMObj_New((BitMapPtr)*itself_color->portPixMap);
  146.                 if ( strcmp(name, "grafVars") == 0 )
  147.                     return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->visRgn);
  148.                 if ( strcmp(name, "chExtra") == 0 )
  149.                     return Py_BuildValue("h", itself_color->chExtra);
  150.                 if ( strcmp(name, "pnLocHFrac") == 0 )
  151.                     return Py_BuildValue("h", itself_color->pnLocHFrac);
  152.                 if ( strcmp(name, "bkPixPat") == 0 )
  153.                     return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->bkPixPat);
  154.                 if ( strcmp(name, "rgbFgColor") == 0 )
  155.                     return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbFgColor);
  156.                 if ( strcmp(name, "rgbBkColor") == 0 )
  157.                     return Py_BuildValue("O&", QdRGB_New, &itself_color->rgbBkColor);
  158.                 if ( strcmp(name, "pnPixPat") == 0 )
  159.                     return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->pnPixPat);
  160.                 if ( strcmp(name, "fillPixPat") == 0 )
  161.                     return Py_BuildValue("O&", ResObj_New, (Handle)itself_color->fillPixPat);
  162.             } else {
  163.                 /* Mono-only attributes */
  164.                 if ( strcmp(name, "portBits") == 0 )
  165.                     return BMObj_New(&self->ob_itself->portBits);
  166.                 if ( strcmp(name, "bkPat") == 0 )
  167.                     return Py_BuildValue("s#", (char *)&self->ob_itself->bkPat, sizeof(Pattern));
  168.                 if ( strcmp(name, "fillPat") == 0 )
  169.                     return Py_BuildValue("s#", (char *)&self->ob_itself->fillPat, sizeof(Pattern));
  170.                 if ( strcmp(name, "pnPat") == 0 )
  171.                     return Py_BuildValue("s#", (char *)&self->ob_itself->pnPat, sizeof(Pattern));
  172.             }
  173.             /*
  174.             ** Accessible for both color/mono windows.
  175.             ** portVersion is really color-only, but we put it here
  176.             ** for convenience
  177.             */
  178.             if ( strcmp(name, "portVersion") == 0 )
  179.                 return Py_BuildValue("h", itself_color->portVersion);
  180.             if ( strcmp(name, "device") == 0 )
  181.                 return PyInt_FromLong((long)self->ob_itself->device);
  182.             if ( strcmp(name, "portRect") == 0 )
  183.                 return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->portRect);
  184.             if ( strcmp(name, "visRgn") == 0 )
  185.                 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->visRgn);
  186.             if ( strcmp(name, "clipRgn") == 0 )
  187.                 return Py_BuildValue("O&", ResObj_New, (Handle)self->ob_itself->clipRgn);
  188.             if ( strcmp(name, "pnLoc") == 0 )
  189.                 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnLoc);
  190.             if ( strcmp(name, "pnSize") == 0 )
  191.                 return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself->pnSize);
  192.             if ( strcmp(name, "pnMode") == 0 )
  193.                 return Py_BuildValue("h", self->ob_itself->pnMode);
  194.             if ( strcmp(name, "pnVis") == 0 )
  195.                 return Py_BuildValue("h", self->ob_itself->pnVis);
  196.             if ( strcmp(name, "txFont") == 0 )
  197.                 return Py_BuildValue("h", self->ob_itself->txFont);
  198.             if ( strcmp(name, "txFace") == 0 )
  199.                 return Py_BuildValue("h", (short)self->ob_itself->txFace);
  200.             if ( strcmp(name, "txMode") == 0 )
  201.                 return Py_BuildValue("h", self->ob_itself->txMode);
  202.             if ( strcmp(name, "txSize") == 0 )
  203.                 return Py_BuildValue("h", self->ob_itself->txSize);
  204.             if ( strcmp(name, "spExtra") == 0 )
  205.                 return Py_BuildValue("O&", PyMac_BuildFixed, self->ob_itself->spExtra);
  206.             /* XXXX Add more, as needed */
  207.             /* This one is so we can compare grafports: */
  208.             if ( strcmp(name, "_id") == 0 )
  209.                 return Py_BuildValue("l", (long)self->ob_itself);
  210.         }""")
  211.  
  212. class MyBMObjectDefinition(GlobalObjectDefinition):
  213.     def outputCheckNewArg(self):
  214.         Output("if (itself == NULL) return PyMac_Error(resNotFound);")
  215.     def outputStructMembers(self):
  216.         # We need to more items: a pointer to privately allocated data
  217.         # and a python object we're referring to.
  218.         Output("%s ob_itself;", self.itselftype)
  219.         Output("PyObject *referred_object;")
  220.         Output("BitMap *referred_bitmap;")
  221.     def outputInitStructMembers(self):
  222.         Output("it->ob_itself = %sitself;", self.argref)
  223.         Output("it->referred_object = NULL;")
  224.         Output("it->referred_bitmap = NULL;")
  225.     def outputCleanupStructMembers(self):
  226.         Output("Py_XDECREF(self->referred_object);")
  227.         Output("if (self->referred_bitmap) free(self->referred_bitmap);")
  228.     def outputGetattrHook(self):
  229.         Output("""if ( strcmp(name, "baseAddr") == 0 )
  230.             return PyInt_FromLong((long)self->ob_itself->baseAddr);
  231.         if ( strcmp(name, "rowBytes") == 0 )
  232.             return PyInt_FromLong((long)self->ob_itself->rowBytes);
  233.         if ( strcmp(name, "bounds") == 0 )
  234.             return Py_BuildValue("O&", PyMac_BuildRect, &self->ob_itself->bounds);
  235.         /* XXXX Add more, as needed */
  236.         if ( strcmp(name, "bitmap_data") == 0 )
  237.             return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(BitMap));
  238.         if ( strcmp(name, "pixmap_data") == 0 )
  239.             return PyString_FromStringAndSize((char *)self->ob_itself, sizeof(PixMap));
  240.         """)
  241.         
  242. # This object is instanciated once, and will access qd globals.
  243. class QDGlobalsAccessObjectDefinition(ObjectDefinition):
  244.     def outputStructMembers(self):
  245.         pass
  246.     def outputNew(self):
  247.         Output()
  248.         Output("%sPyObject *%s_New()", self.static, self.prefix)
  249.         OutLbrace()
  250.         Output("%s *it;", self.objecttype)
  251.         Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
  252.         Output("if (it == NULL) return NULL;")
  253.         Output("return (PyObject *)it;")
  254.         OutRbrace()
  255.     def outputConvert(self):
  256.         pass
  257.     def outputCleanupStructMembers(self):
  258.         pass
  259.  
  260.     def outputGetattrHook(self):
  261.         Output("""
  262.     if ( strcmp(name, "arrow") == 0 )
  263.         return PyString_FromStringAndSize((char *)&qd.arrow, sizeof(qd.arrow));
  264.     if ( strcmp(name, "black") == 0 ) 
  265.         return PyString_FromStringAndSize((char *)&qd.black, sizeof(qd.black));
  266.     if ( strcmp(name, "white") == 0 ) 
  267.         return PyString_FromStringAndSize((char *)&qd.white, sizeof(qd.white));
  268.     if ( strcmp(name, "gray") == 0 ) 
  269.         return PyString_FromStringAndSize((char *)&qd.gray, sizeof(qd.gray));
  270.     if ( strcmp(name, "ltGray") == 0 ) 
  271.         return PyString_FromStringAndSize((char *)&qd.ltGray, sizeof(qd.ltGray));
  272.     if ( strcmp(name, "dkGray") == 0 ) 
  273.         return PyString_FromStringAndSize((char *)&qd.dkGray, sizeof(qd.dkGray));
  274.     if ( strcmp(name, "screenBits") == 0 ) 
  275.         return BMObj_New(&qd.screenBits);
  276.     if ( strcmp(name, "thePort") == 0 ) 
  277.         return GrafObj_New(qd.thePort);
  278.     if ( strcmp(name, "randSeed") == 0 ) 
  279.         return Py_BuildValue("l", &qd.randSeed);
  280.         """)
  281.  
  282. # Create the generator groups and link them
  283. module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
  284. ##r_object = Region_ObjectDefinition('Region', 'QdRgn', 'RgnHandle')
  285. ##po_object = Polygon_ObjectDefinition('Polygon', 'QdPgn', 'PolyHandle')
  286. ##module.addobject(r_object)
  287. ##module.addobject(po_object)
  288. gr_object = MyGRObjectDefinition("GrafPort", "GrafObj", "GrafPtr")
  289. module.addobject(gr_object)
  290. bm_object = MyBMObjectDefinition("BitMap", "BMObj", "BitMapPtr")
  291. module.addobject(bm_object)
  292. qd_object = QDGlobalsAccessObjectDefinition("QDGlobalsAccess", "QDGA", "XXXX")
  293. module.addobject(qd_object)
  294.  
  295.  
  296. # Create the generator classes used to populate the lists
  297. Function = OSErrFunctionGenerator
  298. Method = OSErrMethodGenerator
  299.  
  300. # Create and populate the lists
  301. functions = []
  302. methods = []
  303. execfile(INPUTFILE)
  304. #execfile(EXTRAFILE)
  305.  
  306. # add the populated lists to the generator groups
  307. # (in a different wordl the scan program would generate this)
  308. for f in functions: module.add(f)
  309. ##for f in r_methods: r_object.add(f)
  310. ##for f in po_methods: po_object.add(f)
  311.  
  312. #
  313. # We manually generate a routine to create a BitMap from python data.
  314. #
  315. BitMap_body = """
  316. BitMap *ptr;
  317. PyObject *source;
  318. Rect bounds;
  319. int rowbytes;
  320. char *data;
  321.  
  322. if ( !PyArg_ParseTuple(_args, "O!iO&", &PyString_Type, &source, &rowbytes, PyMac_GetRect,
  323.         &bounds) )
  324.     return NULL;
  325. data = PyString_AsString(source);
  326. if ((ptr=(BitMap *)malloc(sizeof(BitMap))) == NULL )
  327.     return PyErr_NoMemory();
  328. ptr->baseAddr = (Ptr)data;
  329. ptr->rowBytes = rowbytes;
  330. ptr->bounds = bounds;
  331. if ( (_res = BMObj_New(ptr)) == NULL ) {
  332.     free(ptr);
  333.     return NULL;
  334. }
  335. ((BitMapObject *)_res)->referred_object = source;
  336. Py_INCREF(source);
  337. ((BitMapObject *)_res)->referred_bitmap = ptr;
  338. return _res;
  339. """
  340.     
  341. f = ManualGenerator("BitMap", BitMap_body)
  342. f.docstring = lambda: """Take (string, int, Rect) argument and create BitMap"""
  343. module.add(f)
  344.  
  345. #
  346. # And again, for turning a correctly-formatted structure into the object
  347. #
  348. RawBitMap_body = """
  349. BitMap *ptr;
  350. PyObject *source;
  351.  
  352. if ( !PyArg_ParseTuple(_args, "O!", &PyString_Type, &source) )
  353.     return NULL;
  354. if ( PyString_Size(source) != sizeof(BitMap) && PyString_Size(source) != sizeof(PixMap) ) {
  355.     PyErr_BadArgument();
  356.     return NULL;
  357. }
  358. ptr = (BitMapPtr)PyString_AsString(source);
  359. if ( (_res = BMObj_New(ptr)) == NULL ) {
  360.     return NULL;
  361. }
  362. ((BitMapObject *)_res)->referred_object = source;
  363. Py_INCREF(source);
  364. return _res;
  365. """
  366.     
  367. f = ManualGenerator("RawBitMap", RawBitMap_body)
  368. f.docstring = lambda: """Take string BitMap and turn into BitMap object"""
  369. module.add(f)
  370.  
  371. # generate output (open the output file as late as possible)
  372. SetOutputFileName(OUTPUTFILE)
  373. module.generate()
  374. SetOutputFile() # Close it
  375.